package com.ys.controller.web.flow;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.bo.util.MapUtil;
import com.ys.entity.flow.YspDef;
import com.ys.entity.flow.YspDefNode;
import com.ys.entity.flow.YspDeploy;
import com.ys.entity.flow.YspModel;
import com.ys.entity.flow.YspTask;
import com.ys.entity.flow.YspTaskAudit;
import com.ys.entity.flow.YspTaskAuditUser;
import com.ys.entity.sys.TsUserInfo;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.flow.YspDefNodeEnum;
import com.ys.enume.flow.YspTaskAuditEnum;
import com.ys.enume.flow.YspTaskAuditUserEnum;
import com.ys.service.sys.ImgcodeService;
import com.ys.util.DateUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.W;

import lombok.AllArgsConstructor;
import lombok.Data;

@Controller
@RequestMapping("/web/flow/ysp")
public class WebYspController {
	
    @Autowired
    private ImgcodeService imgcodeService;
	
	/**
	 * 任务中心
	 */
	@GetMapping("/toIndex")
	public String toIndex(Model model,
			String loginName,
			String pass){
		
		String loginUserId = ShiroUtils.getUserId();
		if (loginUserId == null || loginUserId.length() == 0) {
			if (loginName != null && loginName.length() > 0 && pass != null && pass.length() > 0) {

				TsUserInfo tsUserInfo = new TsUserInfo().setUserId(loginName).setUserPassWord(pass).queryFirst();
				if (tsUserInfo != null) {
					imgcodeService.doAuthAfterLogin(tsUserInfo);
				}
			} else {
				return "/login";
			}
		} else {
			if (loginName != null && loginName.length() > 0 && pass != null && pass.length() > 0 && !loginUserId.equals(loginName)) {

				TsUserInfo tsUserInfo = new TsUserInfo().setUserId(loginName).setUserPassWord(pass).queryFirst();
				if (tsUserInfo != null) {
					imgcodeService.doAuthAfterLogin(tsUserInfo);
				}
			}
		}

		return "flow/index";
	}
	@Data
	@AllArgsConstructor
	private static class ToIndexDto{
		private Long id; // 
		private String info; // 
	}
	
	/**
	 * 表单数据
	 */
	@GetMapping("/toForm")
	public String toForm(Model model, String bid){
		
		if (bid == null || bid.length() == 0) {
			return W.error(model, "单号不能为空");
		}
		
		YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
		
		// 任务审核点ID-审核用户 MAP
		Map<Long, List<YspTaskAuditUser>> MAP_AUDITID_LISTUSER = new HashMap<Long, List<YspTaskAuditUser>>();
		{
			List<YspTaskAuditUser> listYspTaskAuditUser = new YspTaskAuditUser().setTaskId(ysProcInst.getTaskId()).queryList();
			for(YspTaskAuditUser yspTaskAuditUser : listYspTaskAuditUser) {
				Long taskAuditId = yspTaskAuditUser.getTaskAuditId();
				List<YspTaskAuditUser> listSub = MAP_AUDITID_LISTUSER.containsKey(taskAuditId) ? MAP_AUDITID_LISTUSER.get(taskAuditId) : new ArrayList<YspTaskAuditUser>();
				listSub.add(yspTaskAuditUser);
				MAP_AUDITID_LISTUSER.put(taskAuditId, listSub);
			}
		}
		
		List<YspTaskAudit> listYspTaskAudit = new YspTaskAudit().setTaskId(ysProcInst.getTaskId()).queryList();
		
		List<ToAuditDto.RowDto> rows = new ArrayList<ToAuditDto.RowDto>();
		for(YspTaskAudit yspTaskAudit : listYspTaskAudit) {
			Integer state = yspTaskAudit.getState();
			String stateName = YspTaskAuditEnum.State.getName(state);
			String time = state != YspTaskAuditEnum.State.FOR_AUDIT.value ? DateUtil.getYYYY_MM_DD_HH_mm_ss(yspTaskAudit.getCreateTime()) : null;
			String remark = yspTaskAudit.getOpinion();
			List<ToAuditDto.RowDto.AuditorDto> auditorArr = new ArrayList<ToAuditDto.RowDto.AuditorDto>();
			List<YspTaskAuditUser> listYspTaskAuditUser = MAP_AUDITID_LISTUSER.get(yspTaskAudit.getId());
			for(YspTaskAuditUser yspTaskAuditUser : listYspTaskAuditUser) {
				String stateName2 = YspTaskAuditUserEnum.State.getName(yspTaskAuditUser.getState());
				String auditor = yspTaskAuditUser.getUserId();
				auditorArr.add(new ToAuditDto.RowDto.AuditorDto(stateName2, auditor, auditorArr));
			}
			rows.add(new ToAuditDto.RowDto(stateName, time, remark, auditorArr));
		}
		
		YspTask yspTask = new YspTask().setId(ysProcInst.getTaskId()).queryFirst();
		YspDef yspDef = new YspDef().setId(yspTask.getDefId()).queryFirst();
		YspDeploy yspDeploy = new YspDeploy().setId(yspDef.getDeployId()).queryFirst();
		String info = yspDeploy.getInfo();
		ToAuditDto dto = new ToAuditDto(rows, info);
		model.addAttribute("dto", dto);
		
		return "flow/ysp/toForm";
	}
	@Data
	@AllArgsConstructor
	private static class ToFormDto{
		private List<RowDto> rows;
		private String info; // 

		@Data
		@AllArgsConstructor
		private static class RowDto{
			private String stateName;
			private String time; // 
			private String remark;
			private List<AuditorDto> auditorArr;

			@Data
			@AllArgsConstructor
			private static class AuditorDto{
				private String stateName;
				private String userId;
				private List<AuditorDto> auditorArr;
			}
		}
	}
	
	/**
	 * 流程跟踪
	 */
	@GetMapping("/toAudit")
	public String toAudit(Model model, String bid){
		
		if (bid == null || bid.length() == 0) {
			return W.error(model, "单号不能为空");
		}
		
		
		YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
		
		// 任务审核点ID-审核用户 MAP
		Map<Long, List<YspTaskAuditUser>> MAP_AUDITID_LISTUSER = new HashMap<Long, List<YspTaskAuditUser>>();
		Map<String, String> MAP_ID_NAME = new HashMap<String, String>();
		{
			List<Map<String, Object>> listYspTaskAuditUser = new YspTaskAuditUser().setTaskId(ysProcInst.getTaskId())
					.addLeftJoin("TS_UserInfo B ON B.UserId = A.UserId")
					.addField("B.UserName userName")
					.queryMap();
			try {
				for(Map<String, Object> map : listYspTaskAuditUser) {
					YspTaskAuditUser yspTaskAuditUser = (YspTaskAuditUser) MapUtil.mapToObject(map, YspTaskAuditUser.class);
					Long taskAuditId = yspTaskAuditUser.getTaskAuditId();
					List<YspTaskAuditUser> listSub = MAP_AUDITID_LISTUSER.containsKey(taskAuditId) ? MAP_AUDITID_LISTUSER.get(taskAuditId) : new ArrayList<YspTaskAuditUser>();
					listSub.add(yspTaskAuditUser);
					MAP_AUDITID_LISTUSER.put(taskAuditId, listSub);
					MAP_ID_NAME.put(yspTaskAuditUser.getUserId(), map.get("userName").toString());
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		
		List<YspTaskAudit> listYspTaskAudit = new YspTaskAudit().setTaskId(ysProcInst.getTaskId()).queryList();
		
		List<ToAuditDto.RowDto> rows = new ArrayList<ToAuditDto.RowDto>();
		for(YspTaskAudit yspTaskAudit : listYspTaskAudit) {
			Integer state = yspTaskAudit.getState();
			String stateName = YspTaskAuditEnum.State.getName(state);
			String time = state != YspTaskAuditEnum.State.FOR_AUDIT.value ? DateUtil.getYYYY_MM_DD_HH_mm_ss(yspTaskAudit.getUpdateTime()) : null;
			String remark = yspTaskAudit.getOpinion();
			List<ToAuditDto.RowDto.AuditorDto> auditorArr = new ArrayList<ToAuditDto.RowDto.AuditorDto>();
			List<YspTaskAuditUser> listYspTaskAuditUser = MAP_AUDITID_LISTUSER.get(yspTaskAudit.getId());
			YspDefNode yspDefNode = new YspDefNode().setId(yspTaskAudit.getNodeIdCurrent()).queryFirst();
			if (yspDefNode.getType() == YspDefNodeEnum.Type.END.value) {
				
			} else {
				for(YspTaskAuditUser yspTaskAuditUser : listYspTaskAuditUser) {
					String stateName2 = YspTaskAuditUserEnum.State.getName(yspTaskAuditUser.getState());
					String auditor = yspTaskAuditUser.getUserId() + "(" + MAP_ID_NAME.get(yspTaskAuditUser.getUserId()) + ")";
					auditorArr.add(new ToAuditDto.RowDto.AuditorDto(stateName2, auditor, auditorArr));
				}
			}
			rows.add(new ToAuditDto.RowDto(stateName, time, remark, auditorArr));
		}
		
		YspTask yspTask = new YspTask().setId(ysProcInst.getTaskId()).queryFirst();
		YspDef yspDef = new YspDef().setId(yspTask.getDefId()).queryFirst();
		YspDeploy yspDeploy = new YspDeploy().setId(yspDef.getDeployId()).queryFirst();
		String info = yspDeploy.getInfo();
		ToAuditDto dto = new ToAuditDto(rows, info);
		model.addAttribute("dto", dto);
		
		return "flow/ysp/toAudit";
	}
	@Data
	@AllArgsConstructor
	private static class ToAuditDto{
		private List<RowDto> rows;
		private String info; // 

		@Data
		@AllArgsConstructor
		private static class RowDto{
			private String stateName;
			private String time; // 
			private String remark;
			private List<AuditorDto> auditorArr;

			@Data
			@AllArgsConstructor
			private static class AuditorDto{
				private String stateName;
				private String userId;
				private List<AuditorDto> auditorArr;
			}
		}
	}
	
	/**
	 * 在线设计
	 */
	@GetMapping("/toDesign")
	public String toDesign(Model model, Long id){
		
		if (id == null) {
			return W.error(model, "ID不能为空");
		}
		
		YspModel entity = new YspModel().setId(id).queryFirst();
		String info = entity.getInfo();
		ToDesignDto dto = new ToDesignDto(id, info);

		model.addAttribute("dto", dto);
		return "sys/yspModel/toDesign";
	}
	@Data
	@AllArgsConstructor
	private static class ToDesignDto{
		private Long id; // 
		private String info; // 
	}
	
	/**
	 * 部署
	 */
	@GetMapping("/toDeploy")
	public String toDeploy(Model model, Long id){
		
		if (id == null) {
			return W.error(model, "ID不能为空");
		}
		
		YspModel entity = new YspModel().setId(id).queryFirst();
		String name = entity.getName();
		Integer versionCurrent = entity.getVersionLatest();
		Integer versionNext = versionCurrent + 1;
		ToDeployDto dto = new ToDeployDto(id, name, versionCurrent, versionNext);

		model.addAttribute("dto", dto);
		return "sys/yspModel/toDeploy";
	}
	@Data
	@AllArgsConstructor
	private static class ToDeployDto{
		private Long id; // 
		private String name; // 
		private Integer versionCurrent; //
		private Integer versionNext; // 
	}
}
